package modelz;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public abstract class UpdateableCollection<T extends Updateable<T>> implements UpdateListener<T>, Iterable<T> {

	private final ObjectFactory client;
	private final List<UpdateableCollectionListener<T>> listeners = new CopyOnWriteArrayList<UpdateableCollectionListener<T>>();

	protected UpdateableCollection(ObjectFactory client) {
		this.client = client;
	}
	public final void updated(T item) {
		if( item == null )
			return;
		item.removeListener(this);
		for( UpdateableCollectionListener<T> listener : listeners )
			listener.added(item);
	}

	public final void remove(T item) {
		if( item == null )
			return;
		performRemove(item);
		for( UpdateableCollectionListener<T> listener : listeners )
			listener.removed(item);
	}

	public final T createInstance(Class<T> cls) throws InstantiationException {
		try {
			T item = client.createObject(cls);
			item.addListener(this, false);
			return item;
		} catch( Exception e ) {
			throw new InstantiationException(e.getMessage());
		}
	}
	
	public void clear() {
		performClear();
		for( UpdateableCollectionListener<T> listener : listeners )
			listener.cleared();
	}

	public void addListener(UpdateableCollectionListener<T> listener) {
		listeners.add(listener);
		for( T item : this )
			listener.added(item);
	}

	public void removeListener(UpdateableCollectionListener<T> listener) {
		listeners.remove(listener);
	}
	
	
	protected abstract void performRemove(T item);
	protected abstract void performClear();
	public abstract int size();
	public abstract Iterator<T> iterator();
	
}
